﻿// to config: $$logLevel.Enabled
$setto(this,{
logLevel: {
	ALL: -999999,
	OFF: 999999,
	TRACE: 1000,
	DEBUG: 2000,
	INFO: 3000,
	WARN: 4000,
	ERROR: 5000,
	FATAL: 6000,
	names:['all', 'trace', 'debug', 'info', 'warn', 'error', 'fatal', 'off'],
    Enabled: true
},
logMaster: function(name){
	this._name = name;
	this._appenders = [];	
},
logAppender_List: function(){
    this._list = [];
    this.doAppend = function (evt) { this._list.push(evt); };
    this.getList = function () { return this._list; };
    this.clearList = function () { this._list.splice(0, this._list.length); };
},
logViewer_Window: function(logger){
	this._appender = new logAppender_List();
	logger.addAppender(this._appender);
	this._width = 320;
	this._height = 480;	
    this.clear = function () {
	    if (this._win){ this._win.clearLog(); }
    };
    this.hide = function () {
	    if (this._win){ this._win.close(); }
    };
    this.show = function () {
	    if (this._win == null || this._win.closed) {
	        var u = $U.setParam('logview.htm',"refresh",new Date().toNumString(true)); // auto renew page
		    this._win = this.showDialog(u, {appender:this._appender},
			    {width:this._width + 'px', height:this._height + 'px',
			    left:(screen.availWidth - this._width), top:1, dependent:'yes'});
	    }
    };
    this.showDialog = function(url, args, features) {
	    if (!features) features = {};
	    if (!args) args = {};
	    args.opener = window;
	    var dialog;
	    if (features.dependent && 'showModelessDialog' in window) {
		    if (features.resizable == null) features.resizable = 1;
		    if (features.status == null) features.status = 0;
		    var f = [];
		    if (features.width) f.push('dialogWidth:' + features.width);
		    if (features.height) f.push('dialogHeight:' + features.height);
		    if (features.top) f.push('dialogTop:' + features.top);
		    if (features.left) f.push('dialogLeft:' + features.left);
		    for (var key in features) {
			    if (features.hasOwnProperty(key))
				    f.push(key + ':' + features[key]);
		    }
		    dialog = window.showModelessDialog(url, args, f.join(';'));
		    dialog.moveBy = function (x, y) {
			    if (x) this.dialogLeft = parseInt(this.dialogLeft) + x + 'px';
			    if (y) this.dialogTop = parseInt(this.dialogTop) + y + 'px';
		    }
		    dialog.resizeBy = function (x, y) {
			    if (x) this.dialogWidth = parseInt(this.dialogWidth) + x + 'px';
			    if (y) this.dialogHeight = parseInt(this.dialogHeight) + y + 'px';
		    }
		    dialog.opener = window;
	    } else {
		    var f = [];
		    for (var key in features) {
			    if (features.hasOwnProperty(key))
				    f.push(key + '=' + features[key]);
		    }
		    dialog = window.open(url, 'dialog', f.join(','));
		    dialog.dialogArguments = args;
	    }
	    return dialog;
    };
}});

$setto(logMaster.prototype,{
addAppender: function (appender){
	if (!this._appenders.contains(appender)){
		this._appenders.push(appender);
    }
},
getAppenders: function (){ return this._appenders.slice(0, this._appenders.length); },
clearAppenders: function (){ this._appenders.splice(0, this._appenders.length); },
_log: function (level, msgs, date) {
	var message = msgs.length > 1 ? msgs.join(", ") : msgs[0];
	for (var i = 0, size = this._appenders.length; i < size; i++) {
		this._appenders[i].doAppend({level:level, message:message, time:date});
	}
},
log: function (level) { this._log(level, $A(arguments).slice(1), new Date()); },
trace: function () { this._log(logLevel.TRACE, arguments, new Date()); },
debug: function () { this._log(logLevel.DEBUG, arguments, new Date()); },
info: function () { this._log(logLevel.INFO, arguments, new Date()); },
warn: function () { this._log(logLevel.WARN, arguments, new Date()); },
error: function () { this._log(logLevel.ERROR, arguments, new Date()); },
fatal: function () { this._log(logLevel.FATAL, arguments, new Date()); }
});

$setto(logLevel,this.$$logLevel);
if (logLevel.Enabled){
	var $log = new logMaster('default');
	$setto($log,{
		viewer: new logViewer_Window($log),
		show: function (){ this.viewer.show(); },
		hide: function (){ this.viewer.hide(); },
		clear: function (){ this.viewer.clear(); },
		// Ctrl+Alt+L or Ctrl+Alt+Right Click to view logs
		handler: function(evt){ if (evt.ctrlKey && evt.altKey && (evt.keyCode == 76 || evt.button == 2)) $log.show(); },
		init: function(){
			if ('addEventListener' in document){
			    document.addEventListener('keydown', this.handler, false);
			    document.addEventListener('mousedown', this.handler, false);
			} else if ('attachEvent' in document){
			    document.attachEvent('onkeydown', this.handler);
			    document.attachEvent('onmousedown', this.handler);
			}
			window.onerror = function () {
			    this.error(Array.prototype.join.call(arguments, ','));
			    return true;
			}
		}
	});
	// init logger, thus using "log.trace(str), log.error(str) .. " scentences to log messages
	$log.init();
}